package org.zhs.es.test;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;

/**
 * @Author: zhs
 * @Date: 2021/6/24 11:06
 * @Description:
 *
 * 高级查询
 *
 */
public class ESTest_Document_Query {
    public static void main(String[] args) throws IOException {
        //创建ES客户端
        RestHighLevelClient rsClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost",9200,"http")));

        //高级查询
        // --------------全量查询----------------------
        //查询索引中全部的数据
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
//
//
//        //打印每一项结果
//        for(SearchHit hit: hits){
//            System.out.println(hit.getSourceAsString());
//        }

        //------------ 条件查询 ------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age",30)));





        //--------------- 分页查询 -------------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        builder.from(0); //起始位置
//        builder.size(2); //每页条数
//        request.source(builder);


        //----------- 排序 -------------------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        builder.sort("age", SortOrder.ASC); // 指定排序的列和规则
//        request.source(builder);

        //------------- 过滤字段 ------------------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        String[] excludes = {}; //排除
//        String[] includes = {"name"}; //包含
//
//        builder.fetchSource(includes,excludes); //这个方法可以指定包含和排除的字段
//        request.source(builder);


        //-------------- 组合查询 -----------------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        //boolQueryBuilder.must(QueryBuilders.matchQuery("sex","男")); //must必须是 = mysql中的 =
//        //boolQueryBuilder.mustNot(QueryBuilders.matchQuery("age",30)); //mustNot必须不是 = mysql中的 !=
//        boolQueryBuilder.should(QueryBuilders.matchQuery("age",30)); //should = mysql 中的 or
//        boolQueryBuilder.should(QueryBuilders.matchQuery("age",40));
//
//        builder.query(boolQueryBuilder);
//        request.source(builder);


        //--------------- 范围查询 -------------------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("age"); //指定以哪个字段进行范围查询
//        rangeQueryBuilder.gt(30); // gte 大于等于,gt 大于;lte 小于等于,lt 小于
//
//        builder.query(rangeQueryBuilder);
//        request.source(builder);


        //---------------  模糊查询 ------------------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        builder.query(QueryBuilders.fuzzyQuery("name","wangwu").fuzziness(Fuzziness.AUTO));  //指定 Fuzziness.AUTO 表示字符偏差多少,ONE表示1个,TWO表示2个
//        request.source(builder);



        //--------------- 高亮查询 -------------------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "zhangsan");
//
//        HighlightBuilder highlightBuilder = new HighlightBuilder(); //创建高亮
//        highlightBuilder.preTags("<font  color='red'>"); //指定结果的前置标签
//        highlightBuilder.postTags("</font>"); //后置标签
//        highlightBuilder.field("name"); //指定对哪个字段进行高亮
//        builder.highlighter(highlightBuilder);
//
//        builder.query(termQueryBuilder);
//        request.source(builder);


        //------------- 聚合查询(最大值，最小值....) ------------------
//        SearchRequest request = new SearchRequest();
//        request.indices("user"); //指定查询哪个索引
//
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        AggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");
//
//        builder.aggregation(aggregationBuilder);
//
//        builder.query();
//        request.source(builder);

        //------------ 分组查询 ---------------------------------
        SearchRequest request = new SearchRequest();
        request.indices("user"); //指定查询哪个索引

        SearchSourceBuilder builder = new SearchSourceBuilder();
        AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");

        builder.aggregation(aggregationBuilder);

        builder.query();
        request.source(builder);



        //执行后,返回结果
        SearchResponse response = rsClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits(); //获得命中结果
        System.out.println(hits.getTotalHits()); //命中数量
        System.out.println(response.getTook()); //消耗时间
        //打印每一项结果
        for(SearchHit hit: hits){
            System.out.println(hit.getSourceAsString());
        }


        //关闭客户端
        rsClient.close();
    }
}
